# TODO: Verifying the Validity of OSV Intelligence

from .osv_parser import OsvParser

class OsvFilter:

    @classmethod
    def filter(cls, vulnerabilities):
        """
        根据一定的有效性标准过滤 OSV 情报数据。
        :param vulnerabilities: OSV 漏洞记录的列表（List[Dict]）。
        :return: 一个过滤后的有效漏洞列表（List[Dict]）。
        """
        valid_vulnerabilities = []
        
        for vuln in vulnerabilities:
            if cls.is_valid(vuln):
                valid_vulnerabilities.append(vuln)
        
        return valid_vulnerabilities

    @classmethod
    def is_valid(cls, vuln):
        """
        验证单个漏洞记录的有效性。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果漏洞有效返回 True，否则返回 False（bool）。
        """
        return cls.has_required_fields(vuln) and cls.is_relevant(vuln) and cls.has_poc_or_source(vuln)

    @staticmethod
    def has_required_fields(vuln):
        """
        确保漏洞记录包含必要的字段，如描述、受影响的版本、严重性等。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果所有必要字段都存在返回 True，否则返回 False（bool）。
        """
        required_fields = ['description', 'affected_versions', 'severity']
        return all(field in vuln for field in required_fields)

    @staticmethod
    def is_relevant(vuln):
        """
        检查漏洞是否与当前上下文相关（例如版本、包），并验证是否包含有效的参考文献和ARTICLE标签。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果相关返回 True，否则返回 False（bool）。
        """
        return cls.has_commit_reference(vuln) and cls.has_article_tag(vuln)

    @staticmethod
    def has_commit_reference(vuln):
        """
        检查 References 字段中是否包含漏洞修复的 Commit Id。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果包含 Commit Id，返回 True，否则返回 False（bool）。
        """
        if 'references' not in vuln:
            return False
        # 遍历 References 中的每个条目，检查是否有 Commit Id
        for reference in vuln['references']:
            if 'commit' in reference:
                return True
        return False

    @staticmethod
    def has_article_tag(vuln):
        """
        检查漏洞记录中是否包含 ARTICLE 标签。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果包含 ARTICLE 标签，返回 True，否则返回 False（bool）。
        """
        return 'ARTICLE' in vuln.get('tags', [])

    @staticmethod
    def has_poc_or_source(vuln):
        """
        检查漏洞记录中是否有指向二进制、源码或 POC 的链接或描述。
        :param vuln: 单个 OSV 漏洞记录（Dict）。
        :return: 如果包含相关的二进制、源码或 POC，返回 True，否则返回 False（bool）。
        """
        if 'description' in vuln and any(keyword in vuln['description'].lower() for keyword in ['poc', 'source', 'binary', 'proof of concept']):
            return True
        
        if 'references' in vuln:
            # 检查 References 中是否包含相关的源码、二进制或 POC 链接
            for reference in vuln['references']:
                if 'url' in reference and any(keyword in reference['url'].lower() for keyword in ['poc', 'source', 'binary']):
                    return True
        
        return False